<script setup>
import { defineProps, ref, onMounted, reactive } from 'vue'
import EmojiInput from './EmojiInput.vue'
import useUserStore from '@/stores/user.js'
import moment from 'moment'
import CustomerBack from '@/icons/CustomerBack.vue'
import { httpGetReplyApi, httpGetListApi, send } from './plugin.js'
import { ElLoading } from 'element-plus'
import { delete_comment } from '@/api/note_space.js'

const popoverRefs = reactive({})
const imagePrefix = import.meta.env.VITE_IMAGE_SUFFIX
const userStore = useUserStore()
const commentList = ref([])
const sectionWidth = ref(0)

const props = defineProps({
  sourceId: {
    type: Number,
    default: 0,
  },
  sendApi: {
    type: Function,
    default: send,
  },
  getListApi: {
    type: Function,
    default: httpGetListApi,
  },
  getReplyApi: {
    type: Function,
    default: httpGetReplyApi,
  },
  deleteApi: {
    type: Function,
    default: delete_comment,
  },
  commentTotal: {
    type: Number,
    default: 0,
  },
  limit: {
    type: Number,
    default: 5,
  },
})

const emits = defineEmits(['update:commentTotal'])

const handleReply = async (text, replayIndex) => {
  const parent = commentList.value[replayIndex[0]]
  let { children } = parent
  if (!children) {
    children = []
  }
  let replyItem
  if (replayIndex.length === 1) {
    replyItem = parent
  } else {
    replyItem = children[replayIndex[1]]
  }
  const load = ElLoading.service({fullscreen: true})
  const last_id = await props.sendApi({id: replyItem.id, content: text}, true)
  load.close()
  if (!last_id) return
  const item = {
    id: last_id,
    user: getUserInfo(),
    origin_user: replyItem.user,
    time: moment().format('YYYY-MM-DD HH:mm:ss'),
    show_reply: false,
    new: true,
    content: text,
  }
  parent.replies += 1
  if (replayIndex.length === 1) {
    parent.children = [item].concat(children)
  } else {
    parent.children = children.slice(0, replayIndex[1] + 1).concat([item], children.slice(replayIndex[1] + 1))
  }
  popoverRefs[replyItem.id].hide()
  setRepliesHeight(parent)
}

const getUserInfo = () => {
  const { avatar, name, user_info_id } = userStore.info
  return {
    avatar,
    name,
    user_info_id,
  }
}

const handleComment = async (text) => {
  const load = ElLoading.service({fullscreen: true})
  const last_id = await props.sendApi({id: props.sourceId, content: text})
  load.close()
  const item = {
    id: last_id,
    user: getUserInfo(),
    time: moment().format('YYYY-MM-DD HH:mm:ss'),
    content: text,
    show_reply: false,
    childHeight: 0,
    replies: 0,
    new: true,
    children: [],
  }
  commentList.value = [item].concat(commentList.value)
  emits('update:commentTotal', props.commentTotal + 1)
  setCommentListHeight()
}

const deleteComment = async (item, deleteIndex) => {
  await props.deleteApi(item.id).catch(() => null)
  if (deleteIndex.length === 1) {
    commentList.value.splice(deleteIndex[0], 1)
    emits('update:commentTotal', props.commentTotal - 1)
    setCommentListHeight()
  } else {
    commentList.value[deleteIndex[0]].children.splice(deleteIndex[1], 1)
    commentList.value[deleteIndex[0]].replies -= 1
    setRepliesHeight(commentList.value[deleteIndex[0]])
  }
}

const getList = async () => {
  const { list } = await props.getListApi({
    id: props.sourceId,
    limit: props.limit,
    offset: commentList.value.filter(item => !item.new).length,
  }).catch(() => null)
  if (!list) return
  const ids = []
  commentList.value.forEach(t => {
    const {id} = t
    ids.push(id)
  })
  const appendList = list.filter(item => {
    return !ids.includes(item.id)
  })
  if (appendList.length > 0) {
    commentList.value = commentList.value.concat(list.map(item => {
      item.new = false
      return item
    }))
    setCommentListHeight()
  } else {
    emits('update:commentTotal', commentList.value.length)
  }
}

const setCommentListHeight = () => {
  // nextTick(() => {
  //   const h = document.getElementById('comment-list-content')
  //   commentHeight.value = h.offsetHeight
  // })
}

const getReplies = async (item) => {
  if (!item.children) {
    item.children = []
  }
  const childrenLength = item.children.filter(t => !t.new).length
  const { list } = await props.getReplyApi({
    id: item.id,
    limit: props.limit,
    offset: childrenLength
  }).catch(() => null)
  if (!list) return
  const ids = []
  item.children.forEach(t => {
    ids.push(t.id)
  })
  const addList = list.filter(item => {
    return !ids.includes(item.id)
  })
  if (addList.length === 0) {
    item.replies = item.children.length
  } else {
    item.children = item.children.concat(addList.map(t => {
      t.new = false
      return t
    }))
    setRepliesHeight(item)
  }
}

const hideComment = () => {
  commentList.value.splice(props.limit)
  setCommentListHeight()
}

const hideReplies = (item) => {
  item.children = []
  setRepliesHeight(item)
}

const setRepliesHeight = (/*item*/) => {
  // nextTick(() => {
  //   const list = document.getElementById(`sec-comm-list-${item.id}`)
  //   const originHeight = item.childHeight
  //   const newHeight = list.offsetHeight
  //   const subHeight = newHeight - originHeight
  //   commentHeight.value = commentHeight.value + subHeight
  //   item.childHeight = newHeight
  //   setTimeout(() => {
  //     setCommentListHeight()
  //   }, 500)
  // })
}

// const commentHeight = ref(0)

// const

onMounted(() => {
  sectionWidth.value = document.getElementById('comment-section').offsetWidth
  getList()
})
</script>

<template>
  <div class="pd-100" style="min-width: 450px" id="comment-section">
    <emoji-input @send="handleComment" />
    <div class="sec-comm"><!--:style="{height: `${commentHeight}px`}"-->
      <div id="comment-list-content">
        <template v-for="(item, index) in commentList">
          <div class="comment-content">
            <el-image :src="imagePrefix + item.user.avatar" fit="cover" class="avatar">
              <template #error>
                <el-icon>
                  <component is="Avatar" />
                </el-icon>
              </template>
            </el-image>
            <div class="comment-right">
              <div class="font-bold font-size-l flex justify-content-between align-items-center">
                <span class="w-150 multi-line-text">{{ item.user.name }}</span>
                <span
                  class="font-size-s font-normal"
                  style="color: var(--el-text-color-secondary)"
                >{{ item.time.replace("T", " ") }}</span>
              </div>
              <div class="font-size" style="width: calc(100% - 30px)">{{ item.content }}</div>
              <div class="flex gap-30 align-items-center">
                <el-popover
                  :ref="(re) => {popoverRefs[item.id] = re}"
                  trigger="click"
                  placement="bottom-end"
                  :width="sectionWidth-50"
                  @hide="() => item.show_reply = false"
                  @show="() => item.show_reply = true"
                >
                  <template #reference>
                    <el-link type="primary" class="hover padding-lr-10" :underline="false">
                      <el-icon>
                        <CustomerBack />
                      </el-icon>
                      回复
                    </el-link>
                  </template>
                  <template #default>
                    <div>
                      <EmojiInput
                        v-if="item.show_reply"
                        :table-index="item.id"
                        :placeholder="`回复${item.user.name}`"
                        @send="(text) => handleReply(text, [index])"
                      />
                    </div>
                  </template>
                </el-popover>
                <el-popconfirm title="确认删除评论？" @confirm="deleteComment(item, [index])">
                  <template #reference>
                  <span>
                    <el-icon class="more-icon" v-if="item.user.user_info_id === userStore.info.user_info_id">
                    <component is="Delete" />
                  </el-icon>
                  </span>
                  </template>
                </el-popconfirm>
              </div>
              <div class="sec-comm"><!--:style="{height: `${item.childHeight}px`}"-->
                <div :id="`sec-comm-list-${item.id}`">
                  <template
                    v-if="item.children && item.children.length"
                    v-for="(child, k) in item.children"
                  >
                    <div class="comment-content">
                      <el-image :src="imagePrefix + child.user.avatar" fit="cover" class="avatar">
                        <template #error>
                          <el-icon>
                            <component is="Avatar" />
                          </el-icon>
                        </template>
                      </el-image>
                      <div class="comment-right">
                        <div class="font-bold font-size-l flex justify-content-between align-items-center">
                          <span class="w-150 multi-line-text">{{ child.user.name }}</span>
                          <span
                            class="font-size-s font-normal"
                            style="color: var(--el-text-color-secondary)"
                          >{{ child.time.replace("T", " ") }}</span>
                        </div>
                        <div
                          class="font-size" style="width: calc(100% - 30px)"
                        >
                          <span style="color: var(--el-text-color-secondary)">回复</span>
                          <span
                            style="color: var(--el-text-color-primary)"
                            class="font-bold"
                          >{{ child.origin_user.name }}</span>：{{ child.content }}
                        </div>
                        <div class="flex gap-30 align-items-center">
                          <el-popover
                            :ref="(re) => {popoverRefs[child.id] = re}"
                            trigger="click"
                            placement="bottom-end"
                            :width="sectionWidth-50"
                            @hide="() => child.show_reply = false"
                            @show="() => child.show_reply = true"
                          >
                            <template #reference>
                              <el-link type="primary" class="hover padding-lr-10" :underline="false">
                                <el-icon>
                                  <CustomerBack />
                                </el-icon>
                                回复
                              </el-link>
                            </template>
                            <template #default>
                              <div>
                                <EmojiInput
                                  v-if="child.show_reply"
                                  :table-index="child.id"
                                  :placeholder="`回复${child.user.name}`"
                                  @send="(text) => handleReply(text, [index, k])"
                                />
                              </div>
                            </template>
                          </el-popover>
                          <el-popconfirm title="确认删除回复？" @confirm="deleteComment(child, [index, k])">
                            <template #reference>
                        <span>
                          <el-icon class="more-icon" v-if="child.user.user_info_id === userStore.info.user_info_id">
                          <component is="Delete" />
                        </el-icon>
                        </span>
                            </template>
                          </el-popconfirm>
                        </div>
                      </div>
                    </div>
                  </template>
                </div>
              </div>
              <div v-if="item.replies > 0">
                <el-divider content-position="left" class="divider-s">
                  <el-link
                    v-if="item.children && item.replies > item.children.length"
                    :underline="false"
                    type="info"
                    class="font-size-s link"
                    @click="getReplies(item)"
                  >
                    <el-icon>
                      <component is="ArrowDown" />
                    </el-icon>&nbsp;展开{{ item.replies - item.children.length }}条回复
                  </el-link>
                  <el-link
                    v-if="item.children && item.children.length > 0"
                    @click="hideReplies(item)"
                    :underline="false"
                    type="info"
                    class="font-size-s link"
                  >
                    <el-icon>
                      <component is="ArrowUp" />
                    </el-icon>&nbsp;收起
                  </el-link>
                </el-divider>
              </div>
            </div>
          </div>
        </template>
      </div>
    </div>
    <div v-if="commentTotal > limit">
      <el-divider content-position="left" class="divider-s">
        <el-link
          v-if="commentTotal > commentList.length"
          :underline="false"
          type="info"
          class="font-size-s link"
          @click="getList"
        >
          <el-icon>
            <component is="ArrowDown" />
          </el-icon>&nbsp;展开{{ commentTotal - commentList.length }}条评论
        </el-link>
        <el-link
          v-if="commentList.length > limit"
          @click="hideComment"
          :underline="false"
          type="info"
          class="font-size-s link"
        >
          <el-icon>
            <component is="ArrowUp" />
          </el-icon>&nbsp;收起
        </el-link>
      </el-divider>
    </div>
  </div>
</template>

<style scoped lang="scss">
:deep(.el-link:hover) {
  background-color: transparent !important;
}

.divider-s {
  .link + .link {
    margin-left: 20px;
  }
}

.comment-content {
  width: 100%;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 15px 0;
  color: var(--el-text-color-primary);

  .avatar {
    font-size: 30px;
    width: 40px;
    height: 40px;
    overflow: hidden;
    justify-content: center;
    align-items: center;
    display: flex;
    color: #EFEFEF;
    background: #ABABAB;
    border-radius: 100%;
  }

  .comment-right {
    width: calc(100% - 50px);

    .more-icon {
      color: var(--el-color-danger);
      cursor: pointer;
    }
  }
}

.sec-comm {
  height: auto;
}
</style>